﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using DriveBeamEditor.Controls.BeamNG.Forms;
using DriveBeamEditor.Controls.BeamNG.VehiclePartConfig;
using DriveBeamEditor.Controls.General;
using JBeamLibrary.Tools;
using JBeamLibrary.VehicleParts.Elements;
using JBeamLibrary.VehicleParts.Enums;

namespace DriveBeamEditor.Controls.BeamNG.SectionControls
{
    public partial class NodesControl : VehiclePartControl
    {
        #region Fields

        #endregion

        #region Properties

        private ElementPropertyUse PropertyUse
        {
            get { return rbGroupProp.Checked ? ElementPropertyUse.Group : ElementPropertyUse.Single; }
        }

        #endregion

        #region CTORs

        public NodesControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Events

        private void bindingSource_CurrentChanged(object sender, EventArgs e)
        {
            /* No vehicle part loaded */
            if (VehiclePart == null) return;

            /* Update property box title */
            boxNodeProperties.Text =
                bindingSource.Position >= 0 && VehiclePart.NodeSection.Count > 0
                ? string.Format("Node '{0}' properties", VehiclePart.NodeSection[bindingSource.Position])
                : @"Node properties";

            /* Display properties */
            UpdateProperties(bindingSource.Position);
        }

        private void bindingSource_AddingNew(object sender, AddingNewEventArgs e)
        {
            if (DesignMode || VehiclePart == null)
            {
                e.NewObject = new Node("", 0, 0, 0);
                return;
            }

            /* Avoid loop */
            if (e.NewObject is Node) return;

            /* Ask for a name */
            var id = string.Format(@"n{0}", bindingSource.Count);
            using (var input = TextInputForm.GetNew(@"Enter the ID of the new node", @"Node ID", true, "", @"Please provide a node ID"))
            {
                if (input.ShowDialog(this) == DialogResult.OK)
                    id = input.InputText;
            }

            /* Open new vehicle file dialog */
            e.NewObject = new Node(id, 0, 0, 0);
        }

        private void kvcEditor_EditValueChanged(object sender, EventArgs e)
        {
            var editor = sender as KeyValueControl;
            if (editor == null) return;

            /* Set the property value */
            var nodeProperties = VehiclePart.NodeSection.Properties;
            var index = bindingSource.Position;
            nodeProperties.SetPropertyValue(index, editor.Key, PropertyUse, editor.EditValue);
        }

        private void grid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            //if (e.RowIndex < VehiclePart.NodeSection.Count && e.ColumnIndex == 0)
            //    e.Cancel = true;
        }

        private void grid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (Vehicle == null) return;

            //if (e.RowIndex < VehiclePart.NodeSection.Count && e.ColumnIndex == 0)
            //{
            //    var row = grid.Rows[e.RowIndex];
            //    var val = row.Cells[e.ColumnIndex].Value;
            //    var node = Vehicle.FindNode(val.ToStringOrEmpty());
            //    if (node == null) return;

            //    MessageBox.Show(string.Format("A node with the ID '{0}' already exists. Please enter a different ID.", val), @"Duplicate ID", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            //}
        }

        private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            var col = grid.Columns[e.ColumnIndex];
            if (col != columnDeleteNode) return;

            var row = grid.Rows[e.RowIndex];

            /* Remove the row */
            if (!row.IsNewRow)
                grid.Rows.RemoveAt(e.RowIndex);

            /* Add new row */
            else
            {
                bindingSource.EndEdit();
                grid.NotifyCurrentCellDirty(true);
                grid.EndEdit();
                grid.NotifyCurrentCellDirty(false);
            }
        }

        private void rbGroupProp_CheckedChanged(object sender, EventArgs e)
        {
            if (rbGroupProp.Checked)
                OnPropertyUseChanged();
        }

        private void rbInlineProp_CheckedChanged(object sender, EventArgs e)
        {
            if (rbInlineProp.Checked)
                OnPropertyUseChanged();
        }

        #endregion

        #region Methods

        #region Overrides

        public override string ToString()
        {
            return "Nodes";
        }

        #endregion

        #region Display data

        private void BindNodes()
        {
            bindingSource.DataSource = null;

            if (VehiclePart != null)
                bindingSource.DataSource = VehiclePart.NodeSection.ElementCollection;

            grid.Refresh();
        }

        protected override void OnVehiclePartChanged()
        {
            BindNodes();
            base.OnVehiclePartChanged();
        }

        private void OnPropertyUseChanged()
        {
            UpdateProperties(bindingSource.Position);
        }

        private void UpdateProperties(int index)
        {
            foreach (var editor in
                from editor in boxNodeProperties.Controls.OfType<KeyValueControl>()
                select editor
            )
            {
                var val = GroupHelper.GetPropertyValue(VehiclePart.NodeSection, index, editor.Key, PropertyUse);
                editor.SetEditValueSilent(val);
            }
        }

        #endregion

        #endregion
    }
}
